package smallChanges.statements;

import java.io.PrintStream;

import net.sourceforge.pmd.ast.ASTFormalParameter;
import net.sourceforge.pmd.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.ast.ASTPrimitiveType;
import net.sourceforge.pmd.ast.ASTReferenceType;
import net.sourceforge.pmd.ast.JavaParserVisitorAdapter;
import net.sourceforge.pmd.ast.SimpleJavaNode;

public class PrintPMDStatements extends JavaParserVisitorAdapter{

	int currLine = -1;
	int currIndent = 0;
	private PrintStream out;
	
	public PrintPMDStatements() {
		out=System.out;
	}
	
	public PrintPMDStatements(PrintStream out) {
		this.out=out;
	}
	
	private void indent()
	{
		for(int i=0;i<currIndent ;i++)
		{
			out.print("\t");
		}
	}
	//public Object visit(SimpleJavaNode node, Object o)
	private void printNode(SimpleJavaNode node, String prefix)
	{
		//node.dump("STMT: ");
		if( currLine == node.getBeginLine())
		{
			currIndent ++;
		}
		else
		{
			currLine = node.getBeginLine();
			currIndent = 0;
		}
		indent();
		out.println(prefix + ": " +node.getClass().toString() + " " + node.getBeginLine() + " " 
				+ node.getEndLine() + " " + node.getBeginColumn() + " " + node.getEndColumn() + " >> "+ node.getImage());
	}
	
	
	private String getString(SimpleJavaNode node)
	{
		String suffix="";
		if (node instanceof ASTPrimitiveType) {
			ASTPrimitiveType t=(ASTPrimitiveType)node;
			if(t.isArray()) {
				suffix="_array";
			}
		}
		if (node instanceof ASTReferenceType) {
			ASTReferenceType t=(ASTReferenceType)node;
			if(t.isArray()) {
				suffix="_array";
			}
		}
		if (node instanceof ASTFormalParameter) {
			ASTFormalParameter f=(ASTFormalParameter)node;
			if (f.isArray()) {
				suffix="_array";
			}
		}
		if (node instanceof ASTMethodDeclaration) {
			ASTMethodDeclaration m=(ASTMethodDeclaration)node;
			suffix="_"+m.getMethodName();
		}
				
		String s = node.getClass().toString() + suffix + "_" +
		node.getBeginLine() + "_" + 
		node.getBeginColumn() + "_" + 
		node.getEndLine() + "_" + 
		node.getEndColumn();
		
		return s.replace(".", "_").replace("class ", "").replace("net_sourceforge_pmd_ast_","");
	}
	
	private void printChild(SimpleJavaNode node , String parent)
	{
		out.println(parent+ " -> " + getString(node)+";");
	}
	
	
	public Object visit(SimpleJavaNode node, Object o)
	{

		//printNode(node, "SIMPLENODE");
		for(int i =0 ; i < node.jjtGetNumChildren(); i++)
		{
			printChild((SimpleJavaNode) node.jjtGetChild(i), getString(node));
		}

		return super.visit(node,o);
	}
	
	
	/*
	 public Object visit(ASTStatementExpression node, Object o)
	{
		printNode(node, "ASTStatementExpression");
		return super.visit(node, o);
	}

	
	public Object visit(ASTBlockStatement node, Object o)
	{
		printNode(node, "ASTBlocStatment");
		return super.visit(node, o);
	}
	public Object visit(ASTClassOrInterfaceBodyDeclaration node, Object o)
	{
		printNode(node, "ASTClassOrInterfaceBodyDeclaration");
		currIndent ++;
		for(int i =0 ; i < node.jjtGetNumChildren(); i++)
		{
			printNode((SimpleJavaNode) node.jjtGetChild(i), "CHILD");
		}
		currIndent --;
		
		return super.visit(node, o);
	}
	public Object visit(ASTPackageDeclaration node, Object o)
	{
		printNode(node, "ASTPackageDeclaration");
		return super.visit(node, o);
	}
	public Object visit(ASTImportDeclaration node, Object o)
	{
		printNode(node, "ASTImportDeclaration");
		return super.visit(node, o);
	}
	public Object visit(ASTClassOrInterfaceDeclaration node, Object o)
	{
		printNode(node, "ASTClassOrInterfaceDeclaration");
		return super.visit(node, o);
	}*/
	
	// in a for statement:
	// ASTBlockStatement will not work with for loops

	// ASTForeStatement
	// ASTForInit  ASTExpression ASTForUpdate

}
